#include "Invoice.h"

using namespace ecocity;

//---------------------------------------------------------------

Invoice::Invoice( const QDate& date,
                  const Customer& customer )
      // TODO id in invoices
    : m_id( -1 ),
      m_date( date ),
      m_customer( customer ),
      m_state( OPEN )
{
    update_costs( );
}

//---------------------------------------------------------------

bool
Invoice::add_item( const InvoiceItem& item )
{
    m_items.push_back( item );

    update_costs( );

    return true;
}

//---------------------------------------------------------------

bool
Invoice::remove_item( const QString &item_name,
                      int item_quantity,
                      float item_weight )
{
    bool removed = false;

    for ( size_t i = 0; i < m_items.size(); ++i )
    {
        if ( m_items[ i ].product( ).name( ) == item_name
             && m_items[ i ].quantity( ) == item_quantity
             && m_items[ i ].weight( ) == item_weight )
        {
            m_items.erase( m_items.begin() + i );
            removed = true;
            break;
        }
    }

    update_costs( );

    return removed;
}

//---------------------------------------------------------------

void
Invoice::set_state( STATE state )
{
    m_state = state;
}

//---------------------------------------------------------------

int
Invoice::id( ) const
{
    return m_id;
}

//---------------------------------------------------------------

Invoice::STATE
Invoice::state( ) const
{
    return m_state;
}

//---------------------------------------------------------------

const QDate&
Invoice::date( ) const
{
    return m_date;
}

//---------------------------------------------------------------

Customer
Invoice::customer( ) const
{
    return m_customer;
}

//---------------------------------------------------------------

const std::vector< InvoiceItem >&
Invoice::items( ) const
{
    return m_items;
}

//---------------------------------------------------------------

float
Invoice::total_cost( ) const
{
    return m_total_cost;
}

//---------------------------------------------------------------

float
Invoice::cost_without_taxes( ) const
{
    return m_cost_without_taxes;
}

//---------------------------------------------------------------

float
Invoice::taxes_cost( ) const
{
    return m_total_taxes;
}

//---------------------------------------------------------------

float
Invoice::profit( ) const
{
    return m_total_profit;
}

//---------------------------------------------------------------

void
Invoice::update_costs( )
{
    m_cost_without_taxes = 0;
    m_total_taxes = 0;
    m_total_profit = 0;
    m_total_cost = 0;

    for ( uint i = 0; i < m_items.size( ); ++i )
    {
        m_cost_without_taxes += m_items[ i ].untaxed_cost_with_discount( );
        m_total_taxes += m_items[ i ].taxes_cost( );
        m_total_cost += m_items[ i ].total_cost( );
        m_total_profit += m_items[ i ].profit( );
    }
}
